﻿using CheatMenu.Menus;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CheatMenu.Managers
{
    public static class MenuManager
    {
        private static Dictionary<string, MenuBase> menusDict = new Dictionary<string, MenuBase>();
        private static List<MenuBase> menusList = new List<MenuBase>();
        private static List<MenuBase> menusListRemove = new List<MenuBase>();

        public static T GetMenu<T>() where T : MenuBase
        {
            T result = null;

            for (int i = 0; i < menusList.Count; i++)
            {
                if(menusList[i] is T resultMenu)
                {
                    result = resultMenu;
                    break;
                }
            }

            return result;
        }

        public static T GetMenu<T>(string name) where T : MenuBase
        {
            return menusDict?[name] as T;
        }

        public static bool TryGetMenu<T>(string name, out T menu) where T : MenuBase
        {
            bool exists = false;

            if (menusDict?[name] is T resultMenu)
            {
                exists = true;
                menu = resultMenu;
            }
            else
            {
                menu = null;
            }

            return exists;
        }

        public static void HideAll()
        {
            for (int i = 0; i < menusList.Count; i++)
            {
                menusList[i].Shown = false;
            }
        }

        public static void AddMenu(MenuBase menu)
        {
            if (!menusDict.ContainsKey(menu.Name))
            {
                menusDict.Add(menu.Name, menu);
                menusList.Add(menu);
            }
            else
            {
                LogManager.LogWarning($"Trying to add existing menu with name: {menu.Name}");
            }
        }

        public static void RemoveMenu(MenuBase menu)
        {
            if (menusDict.ContainsKey(menu.Name))
            {
                if (!menusListRemove.Contains(menu))
                {
                    menusListRemove.Add(menu);
                }
            }
            else
            {
                LogManager.LogWarning($"Trying to remove non-existing menu with name: {menu.Name}");
            }
        }

        public static void OnUpdate()
        {
            if(menusListRemove.Count > 0)
            {
                for (int i = menusListRemove.Count - 1; i >= 0; i--)
                {
                    MenuBase menu = menusListRemove[i];
                    if(menu.Shown) menu.Shown = false;
                    menusDict.Remove(menu.Name);
                    menusList.Remove(menu);
                    menusListRemove.Remove(menu);
                }
            }
        }

        public static void OnGUI()
        {
            for (int i = 0; i < menusList.Count; i++)
            {
                MenuBase menu = menusList[i];
                if (menu.Shown) menu.OnGUI();
            }
        }

        public static void ReloadMenuGUI()
        {
            for (int i = 0; i < menusList.Count; i++)
            {
                menusList[i].ReinitializeGUI();
            }
        }
    }
}
